﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace Super_Pong.Classes
{
    static class Utils2D
    {
        #region Vector Utils
        /// <summary>
        /// Return the direction between two vectors.
        /// </summary>
        /// <param name="v1">The origin vector.</param>
        /// <param name="v2">The target vector.</param>
        /// <returns>The unity direction vector between the origin and the target.</returns>
        public static Vector2 getDirectionTo(Vector2 v1, Vector2 v2)
        {
            if (v1 != null && v2 != null)
            {
                //Grab the diference vector
                Vector2 ret = (v2 - v1);
                //Normalize it (transform into a unit vector pointing to the same place)
                ret.Normalize();
                //Return it
                return ret;
            }
            else
                return Vector2.Zero;
        }
        
        /// <summary>
        /// Get the distance between a target vector and another.
        /// </summary>
        /// <param name="a">The origin vector.</param>
        /// <param name="b">The target vector.</param>
        /// <returns>The distance between the origin and the target.</returns>
        public static float getDistanceTo(Vector2 a, Vector2 b)
        {
            return (b - a).Length();
        }
        #endregion

        #region General Math utils
        /// <summary>
        /// Linear interpolation between A and B using the transition factor.
        /// Transition is a value between 0 and 1, when 0 returns A and when 1
        /// returns B. Values in between return a step between A and B.
        /// Formula: a + ((b - a) * transition)
        /// </summary>
        /// <param name="a">The starting point.</param>
        /// <param name="b">The ending point.</param>
        /// <param name="transition">The transition value to get the position between a and b.</param>
        /// <returns>The value between a and b were the transition is.</returns>
        public static float lerp(float a, float b, float transition)
        {
            return a + ((b - a) * constrain(transition,0.0f,1.0f));
        }


        /// <summary>
        /// OVERLOAD: int
        /// Linear interpolation between A and B using the transition factor.
        /// Transition is a value between 0 and 1, when 0 returns A and when 1
        /// returns B. Values in between return a step between A and B.
        /// Formula: a + ((b - a) * transition)
        /// </summary>
        /// <param name="a">The starting point.</param>
        /// <param name="b">The ending point.</param>
        /// <param name="transition">The transition value to get the position between a and b.</param>
        /// <returns>The value between a and b were the transition is.</returns>
        public static int lerp(int a, int b, float transition)
        {
            return (int)lerp((float)a, (float)b, transition);
        }

        /// <summary>
        /// OVERLOAD: Byte
        /// Linear interpolation between A and B using the transition factor.
        /// Transition is a value between 0 and 1, when 0 returns A and when 1
        /// returns B. Values in between return a step between A and B.
        /// Formula: a + ((b - a) * transition)
        /// </summary>
        /// <param name="a">The starting point.</param>
        /// <param name="b">The ending point.</param>
        /// <param name="transition">The transition value to get the position between a and b.</param>
        /// <returns>The value between a and b were the transition is.</returns>
        public static byte lerp(byte a, byte b, float transition)
        {
            return (byte)lerp((float)a, (float)b, transition);
        }

        /// <summary>
        /// Constrain the value between min and max.
        /// </summary>
        /// <param name="value">The value to be constrained.</param>
        /// <param name="min">The minimum this value can be.</param>
        /// <param name="max">The maximum this value can be.</param>
        /// <returns>The value constrained between min and max.</returns>
        public static float constrain(float value, float min, float max)
        {
            //Trap the value inside the boundaries
            value = (value > max ? max : (value < min ? min : value));
            //return him
            return value;
        }
        #endregion

        #region Graphics Utils
        /// <summary>
        /// Interpolate between 2 colors using the transition value.
        /// </summary>
        /// <param name="a">The color to start the interpolation.</param>
        /// <param name="b">The color to end the interpolation.</param>
        /// <param name="transition">The value in range 0-1 of the transition between A and B.</param>
        /// <returns>The color between A and B.</returns>
        public static Color lerpColor(Color a, Color b, float transition)
        {
            //Check for valid colors, else return white
            if (a != null && b != null)
            {
                //Create a new color with lerp parameters RGBA
                Color ret = new Color(
                    lerp(a.R, b.R, transition),
                    lerp(a.G, b.G, transition),
                    lerp(a.B, b.B, transition),
                    lerp(a.A, b.A, transition)
                    );
                //Return the new color between A and B
                return ret;
            }
            else
                return Color.White;
        }
        #endregion
    }
}
